package cglib;

import component.genericStrategy.MyBeanFactoryAwareGeneratorStrategy;
import config.FirstConfig;
import org.junit.Test;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author: ZhouBert
 * @date: 2020/9/7
 * @description:	模拟 Spring 的 CGLIB 增强代理（通过自定义策略生成代理类）
 * 由于很多是内部类， 于是采用反射创建该 ConfigurationClassEnhancer 实例。
 */
public class MockCGLIB {

	@Test
	public void testCGLIB() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
		//反射出ConfigurationClassEnhancer，并创建实例
		Class<?> configurationClassEnhancerClass = Class.forName("org.springframework.context.annotation.ConfigurationClassEnhancer");
		Constructor constructor = configurationClassEnhancerClass.getDeclaredConstructor();
		constructor.setAccessible(true);
		Object configurationClassEnhancer = constructor.newInstance();

		//获取属性callbackFilter
		Field callbackFilterField = configurationClassEnhancerClass.getDeclaredField("CALLBACK_FILTER");
		callbackFilterField.setAccessible(true);
		CallbackFilter callbackFilter = (CallbackFilter) callbackFilterField.get(configurationClassEnhancer);

		//反射ConditionalCallbackFilter类
		Class<?> ConditionalCallbackFilter = Class.forName("org.springframework.context.annotation.ConfigurationClassEnhancer$ConditionalCallbackFilter");
		//获取getCallbackTypes方法
		Method getCallbackTypesMethod = ConditionalCallbackFilter.getDeclaredMethod("getCallbackTypes");
		getCallbackTypesMethod.setAccessible(true);


		//反射出EnhancedConfiguration接口
		Class<?> enhancedConfiguration = Class.forName("org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration");

		// 至此，准备结束，开始进入真正的模拟！

		//创建增强类
		Enhancer enhancer = new Enhancer();
		// 模拟类！
		enhancer.setSuperclass(FirstConfig.class);//设置目标类
		enhancer.setInterfaces(new Class<?>[]{enhancedConfiguration});//设置要实现的接口
		enhancer.setUseFactory(false);
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new MyBeanFactoryAwareGeneratorStrategy(this.getClass().getClassLoader()));//生成自定义的策略
		//过滤器
		enhancer.setCallbackFilter(callbackFilter);
		//过滤器类型
		enhancer.setCallbackTypes((Class[]) getCallbackTypesMethod.invoke(callbackFilter));
		//创建代理类
		Class proxy = enhancer.createClass();
		System.out.println(proxy);
	}
}
